﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace BitArrayIndexer
{

    class BitArray
    {
        /// <summary>
        /// Bit数组
        /// </summary>
        private int[] bits;
        /// <summary>
        /// 数组中Bit位数
        /// </summary>
        private int length;
        /// <summary>
        /// 数组需要多少个int
        /// </summary>
        private int size;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="length"></param>
        public BitArray(int length)
        {
            if (length<1)
            {
                throw new ArgumentException();
            }
            size = ((length - 1) >> 5) + 1;
            bits = new int[size]; // (length-1)/32+1
            this.length = length;
        }
        
        public string GetHexString()
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < size;i++ )
            {
                sb.Append(bits[size-i-1].ToString("X8"));
                //string str = bits[size - i - 1].ToString("X8");
                //int iii = int.Parse(str,System.Globalization.NumberStyles.HexNumber);
                //string sss = iii.ToString("X8");
            }
           
            return FormatString(sb.ToString());
        }
        public void ResetHexStringData(string str)
        {
            if (str.Length<1)
            {
                throw new IndexOutOfRangeException();
            }
            length = str.Length*4;
            size = ((length - 1) >> 5) + 1;
            bits = new int[size];

            for (int i = 0; i <size;i++ )
            {
                string ss = str.Substring(i*8, 8);
                int val;
                CallTryParse(ss,NumberStyles.HexNumber,out val);
                bits[size-i-1] = val;
            }
        }
        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public bool this[int index]
        {
            get
            {
                if (index<0 ||index>length)
                {
                    throw new IndexOutOfRangeException();
                }
                return ((bits[index>>5])&(1<<index)) !=0;  //(1<<(index%32))
            }
            set
            {
                if (index<0 ||index>length)
                {
                    throw new IndexOutOfRangeException();
                }
                if (value)
                {
                    bits[index >> 5] |= (1 << index);
                }
                else
                {
                    bits[index >> 5] &= ~(1 << index%32);
                }
            }
        }
        private static void CallTryParse(string stringToConvert, NumberStyles styles, out int val)
        {
            int number;
            CultureInfo provider;

            // If currency symbol is allowed, use en-US culture.

            if ((styles & NumberStyles.AllowCurrencySymbol) > 0)
                provider = new CultureInfo("en-US");
            else
                provider = CultureInfo.InvariantCulture;

            bool result = Int32.TryParse(stringToConvert, styles,
                                         provider, out number);
            if (result)
                Console.WriteLine("Converted '{0}' to {1}.", stringToConvert, number);
            else
                Console.WriteLine("Attempted conversion of '{0}' failed.", Convert.ToString(stringToConvert));
            val = number;
        }

        /// <summary>
        /// 格式化输入字串 两位一组 满16个添加一个“|”
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string FormatString(string str)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(str[0]);
            for (int i = 1; i < str.Length; i++)
            {
                if (0 == i % 2)
                {
                    if (0 == i % 16)
                    {
                        sb.Append(" | " + str[i]);
                    }
                    else
                    {
                        sb.Append(" " + str[i]);
                    }
                }
                else
                {
                    sb.Append(str[i]);
                }
            }
            return sb.ToString();
        }
    }
    //class Test
    //{
    //    public static void Main(string[] args)
    //    {
    //        BitArray ba = new BitArray(50);
    //        ba[40] = true;
    //        bool i = ba[30];

    //    }
    //}
}
